package com.totem.customer.serivce.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.totem.base.constants.CommonConstants;
import com.totem.base.constants.ErrorCode;
import com.totem.base.exception.BaseException;
import com.totem.base.model.PageVO;
import com.totem.base.mybatis.UserIdContext;
import com.totem.base.util.DateUtils;
import com.totem.customer.mapper.TCustomerMapper;
import com.totem.customer.mapper.TFavoritesMapper;
import com.totem.customer.model.TCustomers;
import com.totem.customer.model.TFavorites;
import com.totem.customer.serivce.ITFavoriteService;
import com.totem.customer.vo.FavoritePageVO;
import com.totem.customer.vo.UpdateFavoriteVO;
import com.totem.product.service.ProductCommonService;
import com.totem.product.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TFavoriteServiceImpl extends ServiceImpl<TFavoritesMapper, TFavorites> implements ITFavoriteService {
    @Autowired
    private TCustomerMapper tCustomerMapper;
    @Autowired
    private ProductCommonService productCommonService;

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public boolean updateFavorite(UpdateFavoriteVO vo) {
        Long customerId = UserIdContext.getUserId();
        if(customerId==null){
            throw new BaseException(ErrorCode.UNAUTHORIZED);
        }

        LambdaQueryWrapper<TFavorites> existsWrapper = new LambdaQueryWrapper<>();
        existsWrapper.eq(TFavorites::getCustomerId, customerId);
        existsWrapper.eq(TFavorites::getProductId, vo.getProductId());
        int effect = 0;
        if(baseMapper.exists(existsWrapper)){
            effect = baseMapper.delete(existsWrapper);
        }else{
            TFavorites tFavorites = TFavorites.builder().build();
            tFavorites.setCustomerId(customerId);
            tFavorites.setProductId(vo.getProductId());
            effect = baseMapper.insert(tFavorites);
        }
        return effect>0;
    }

    @Override
    public PageVO<ProductVO> favoritePage(FavoritePageVO vo) {
        Long customerId = UserIdContext.getUserId();
        if(customerId==null){
            throw new BaseException(ErrorCode.UNAUTHORIZED);
        }

        LambdaQueryWrapper<TCustomers> existsWrapper = new LambdaQueryWrapper<>();
        existsWrapper.eq(TCustomers::getId,customerId);
        if(!tCustomerMapper.exists(existsWrapper)){
            log.warn("客户[{}]不存在", customerId);
            throw new BaseException(ErrorCode.NOT_EXIST_CUSTOMER);
        }

        Page<TFavorites> page = new Page<>();
        page.setCurrent(vo.getCurrent());
        page.setSize(vo.getPageSize());

        LambdaQueryWrapper<TFavorites> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TFavorites::getCustomerId, customerId);
        queryWrapper.orderByDesc(TFavorites::getUpdateTime);
        List<TFavorites> favoriteProductList = baseMapper.selectPage(page, queryWrapper).getRecords();
        List<ProductVO> productVOList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(favoriteProductList)){
            Set<Long> favoriteProductIdSet = favoriteProductList.stream().map(TFavorites::getProductId).collect(Collectors.toSet());
            Map<Long, String> productFavoriteTimeMap = favoriteProductList.stream().collect(Collectors.toMap(TFavorites::getProductId,
                    v->DateUtils.formatDate(v.getUpdateTime(), CommonConstants.DEFAULT_DATETIME_FORMAT)));
            if(!CollectionUtils.isEmpty(favoriteProductIdSet)) {
                productVOList = productCommonService.list(List.copyOf(favoriteProductIdSet));
                if(!CollectionUtils.isEmpty(productVOList)){
                    productVOList.forEach(p->{
                        Long productId = p.getProductId();
                        String favoriteTime = productFavoriteTimeMap.get(productId);
                        if(StringUtils.isNotBlank(favoriteTime)) {
                            p.setCreateAt(favoriteTime);
                        }
                    });
                    Collections.sort(productVOList);
                }
            }
        }


        PageVO<ProductVO> pageVO = new PageVO<>();
        pageVO.setList(productVOList);
        pageVO.setTotal(page.getTotal());
        return pageVO;
    }
}
